﻿using PowerMonitor.BaseCtrl;
using PowerMonitor.Common;
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using PowerMonitor.Properties;

namespace PowerMonitor.History
{
    public partial class StatisticChartView : Form
    {
      
        private List<BaseDevice> SelectedDevices = new List<BaseDevice>(); // 完整选择设备
        private List<DataItemTag> LooseSelItem = new List<DataItemTag>();        // 零散选择数据项
        private List<DataItemTag> SelectedItem = new List<DataItemTag>(); // 全部选择的数据项

        public enum eQueryType
        {
            day,
            month,
            year,
            custom
        }
        private eQueryType queryType = eQueryType.day;

        private int LimitSeriesNum = 6;
        public StatisticChartView()
        {
            InitializeComponent();
        }
        private void StatisticChartView_Load(object sender, EventArgs e)
        {
            // Zoom into the X axis
            WaveRecChart.ChartAreas[0].AxisX.ScaleView.Zoom(1, 100);
            // Enable range selection and zooming end user interface
            // WaveRecChart.ChartAreas[0].CursorX.IsUserEnabled = true;
            WaveRecChart.ChartAreas[0].CursorX.IsUserSelectionEnabled = true;
            WaveRecChart.ChartAreas[0].AxisX.ScaleView.Zoomable = true;
            //将滚动内嵌到坐标轴中
            WaveRecChart.ChartAreas[0].AxisX.ScrollBar.IsPositionedInside = true;
            // 设置滚动条的大小
            WaveRecChart.ChartAreas[0].AxisX.ScrollBar.Size = 15;
            //WaveRecChart.ChartAreas[0].AxisX.ScrollBar.BackColor = System.Drawing.Color.LightSeaGreen;
            // 设置滚动条的按钮的风格，下面代码是将所有滚动条上的按钮都显示出来
            WaveRecChart.ChartAreas[0].AxisX.ScrollBar.ButtonStyle = System.Windows.Forms.DataVisualization.Charting.ScrollBarButtonStyles.All;
            // 设置自动放大与缩小的最小量
            WaveRecChart.ChartAreas[0].AxisX.ScaleView.SmallScrollSize = double.NaN;
            WaveRecChart.ChartAreas[0].AxisX.ScaleView.SmallScrollMinSize = 10;
            // Y 轴自适应 曲线在图形中间
            WaveRecChart.ChartAreas[0].AxisY.IsStartedFromZero = true;


            WaveRecChart.Series.Clear();
            WaveRecChart.ResetAutoValues();
            WaveRecChart.ChartAreas[0].AxisX.ScaleView.ZoomReset();

            RefreshChlTree();
        }

       
        private void SetSeriesChartType(System.Windows.Forms.DataVisualization.Charting.Series item)
        {
            if (item == null)
            {
                return;
            }
            item.Label = "";
            item.LegendText = "";
            item.ToolTip = "#VAL{F2}";
            if (rbChartTypeLine.Checked)
            {
                item.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
            }
            else if (rbChartTypePie.Checked)
            {
                item.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Pie;
                item.Label = "#PERCENT{P}";
                item.LegendText = "#VALX";
                item.ToolTip = "#LEGENDTEXT: #VAL{F2}";
            }
            else
            {
                item.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Column;
            }

        }
        public void RefreshChlTree()
        {
            DevTreeview.Nodes.Clear(); // 清空所有
            int count = 0;
            foreach (var chl in AppMain.ChlList)
            {
                TriStateTreeNode chlNode = new TriStateTreeNode(chl.baseChlPara.ChannelName, 1, 0);

                chlNode.CheckboxVisible = true;
                chlNode.IsContainer = true;  // 添加此句才有三态 CheckBox
                chlNode.Tag = chl;
                DevTreeview.Nodes.Add(chlNode);
                //chlNode.Expand();
                for (int i = 0; i < chl.GetDevicesCnt(); i++)
                {
                    var dev = chl.GetDevByIndex(i);
                    TriStateTreeNode devNode = new TriStateTreeNode(dev.Name, 3, 2);
                    devNode.CheckboxVisible = true;
                    devNode.IsContainer = true;  // 添加此句才有三态 CheckBox
                    devNode.Tag = dev;
                    count = 0;
                    List<DevDataItem> itemlist = dev.GetDataList();
                    foreach (var item in itemlist)
                    {
                        if (cbbShowSaveSetted.Checked == true) // 只显示设置了保存的数据项
                        {
                            if (!item.IsSave)
                            {
                                continue;
                            }
                        }
                        if (ckbShowSumOnly.Checked)
                        {
                            if (!item.IsSummation)
                            {
                                continue;
                            }
                        }
                        count++;
                        TriStateTreeNode itemNode = new TriStateTreeNode(item.Name, 3, 2);
                        itemNode.CheckboxVisible = true;
                        DataItemTag itemTag = new DataItemTag((UInt32)chl.baseChlPara.ChannelId, (UInt32)dev.DeviceId, item);
                        itemNode.Tag = itemTag;
                        devNode.Nodes.Add(itemNode);
                    }
                    if (count > 0)
                    {
                        chlNode.Nodes.Add(devNode);
                    }
                }
                //chlNode.Expand();
            }
            if (DevTreeview.Nodes.Count > 0)
            {
                DevTreeview.Nodes[0].Expand();
                if (DevTreeview.Nodes[0].Nodes.Count > 0)
                {
                    DevTreeview.Nodes[0].Nodes[0].Expand();
                }
            }
        }
        /// <summary>
        /// 显示项处理（Checked==true时  只显示设置了存储属性的数据项）
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cbbShowSaveSetted_Click(object sender, EventArgs e)
        {
            RefreshChlTree();
        }
        /// <summary>
        /// 获取选中项
        /// </summary>
        /// <returns>有选中项为true</returns>
        public bool GetSelectedItem()
        {
            SelectedDevices.Clear();
            LooseSelItem.Clear();
            SelectedItem.Clear();
            bool isMoreThanLimit = false;
            if (DevTreeview.Nodes.Count == 0)
            {
                return false;
            }
            try
            {
                foreach (TriStateTreeNode chlNode in DevTreeview.Nodes)
                {
                    foreach (TriStateTreeNode devNode in chlNode.Nodes)
                    {
                        if (devNode.CheckState != CheckState.Unchecked)
                        {
                            if (devNode.CheckState == CheckState.Checked)
                            {
                                SelectedDevices.Add((BaseDevice)devNode.Tag);
                                BaseDevice dev = SelectedDevices[SelectedDevices.Count - 1];
                                List<DevDataItem> itemlist = dev.GetDataList();
                                foreach (var item in itemlist)
                                {
                                    if (cbbShowSaveSetted.Checked == true) // 只显示设置了保存的数据项
                                    {
                                        if (!item.IsSave)
                                        {
                                            continue;
                                        }
                                    }
                                    if (ckbShowSumOnly.Checked)
                                    {
                                        if (!item.IsSummation)
                                        {
                                            continue;
                                        }
                                    }
                                    if (SelectedItem.Count >= LimitSeriesNum)
                                    {
                                        isMoreThanLimit = true;
                                        break;
                                    }
                                    SelectedItem.Add(new DataItemTag((UInt32)dev.ChannelId, (UInt32)dev.DeviceId, item));
                                }
                            }
                            else
                            {
                                foreach (TriStateTreeNode itemNode in devNode.Nodes)
                                {
                                    if (itemNode.Checked)
                                    {
                                        if (SelectedItem.Count >= LimitSeriesNum)
                                        {
                                            isMoreThanLimit = true;
                                            break;
                                        }
                                        LooseSelItem.Add((DataItemTag)itemNode.Tag);
                                        SelectedItem.Add((DataItemTag)itemNode.Tag);
                                    }
                                }
                            }
                        }

                    }
                }
                if (isMoreThanLimit)
                {
                    MessageBox.Show(string.Format(Resources.txtOnlyTopNIsValid, LimitSeriesNum), Properties.Resources.msgTitleTip);
                }
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.Message);
                return false;
            }
            return true;
        }


        private void rbDay_CheckedChanged(object sender, EventArgs e)
        {
            RadioButton rb = sender as RadioButton;
            if (rb == null)
            {
                return;
            }
            dtpFrom.Value = DateTime.Now;
            dtpTo.Value = DateTime.Now;
            lbFrom.Visible = false;
            lbTo.Visible = false;
            dtpTo.Visible = false;
            string strTimeFormat = "yyyy-MM-dd HH:mm";
            switch (Int32.Parse(rb.Tag.ToString()))
            {
                case 0: // 日报
                    strTimeFormat = "yyyy-MM-dd";
                    dtpFrom.Width = 100;
                    dtpFrom.ShowUpDown = false;
                    queryType = eQueryType.day;
                    break;
                case 1: // 月报
                    strTimeFormat = "yyyy-MM";
                    dtpFrom.Width = 80;
                    dtpFrom.ShowUpDown = true;
                    queryType = eQueryType.month;
                    break;
                case 2: // 年报
                    strTimeFormat = "yyyy";
                    dtpFrom.Width = 60;
                    dtpFrom.ShowUpDown = true;
                    queryType = eQueryType.year;
                    break;
                case 3: // 自定义时间段
                    strTimeFormat = "yyyy-MM-dd HH:mm";
                    lbFrom.Visible = true;
                    dtpFrom.ShowUpDown = false;
                    dtpFrom.Value = dtpTo.Value.AddDays(-1);
                    lbTo.Visible = true;
                    dtpTo.Visible = true;
                    dtpFrom.Width = 136;
                    queryType = eQueryType.custom;
                    break;
                default:
                    strTimeFormat = "yyyy-MM-dd";
                    dtpFrom.ShowUpDown = false;
                    break;
            }
            dtpFrom.CustomFormat = strTimeFormat;
        }

        private int GetMonthMaxDay(int year, int month)
        {
            int maxday = 31;
            List<int> Max31 = new List<int> { 1, 3, 5, 7, 8, 10, 12 };
            List<int> Max30 = new List<int> { 4, 6, 9, 11 };
            if (month > 12 || month < 1)
            {
                return maxday;
            }
            if (Max31.Contains(month))
            {
                return maxday;
            }
            if (Max30.Contains(month))
            {
                return maxday - 1;
            }
            if (year % 4 == 0 || (year % 100 == 0 && year % 400 == 0))
            {
                return 29;
            }
            else
            {
                return 28;
            }
        }

        // 计算最大最小值  DataTable.Compute()
        private void FillDataToChart(eQueryType querytype, Dictionary<UInt64, float> data)
        {
            WaveRecChart.Series.Clear();
            WaveRecChart.Legends.Clear();
            if (data.Count == 0 && querytype == eQueryType.custom || (querytype == eQueryType.custom && rbChartTypePie.Checked))
            {
                return;
            }
            int i;

            UInt64 recordId = 0;
            int maxday = 30, k = 0;
            DevDataItem dataItem = null;

            Dictionary<double, double> intervalValuas;
            Dictionary<DataItemTag, Dictionary<double, double>> recValues = new Dictionary<DataItemTag, Dictionary<double, double>>();
            switch (querytype)
            {
                #region 日报表数据统计
                case eQueryType.day:
                    foreach (var item in SelectedItem)
                    {
                        intervalValuas = new Dictionary<double, double>();
                        if (!item.dataItem.IsSummation) // 瞬时值
                        {
                            if (rbChartTypePie.Checked && rbMeterCompare.Checked) // 设备对标（饼状图）
                            {
                                recordId = (UInt64)((UInt64)item.GlobalId << 32) + (UInt64)(dtpFrom.Value.Day << 16) + (UInt64)(0 << 8);
                                if (data.ContainsKey(recordId))
                                {
                                    intervalValuas.Add(0, data[recordId]);
                                }
                                else
                                {
                                    intervalValuas.Add(0, 0);
                                }
                                goto DAYADD;
                            }
                            for (i = 0; i < 24; i++) // 每行
                            {
                                recordId = (UInt64)((UInt64)item.GlobalId << 32) + (UInt64)(dtpFrom.Value.Day << 16) + (UInt64)(i << 8);
                                if (data.ContainsKey(recordId))
                                {
                                    intervalValuas.Add(i, data[recordId]);
                                }
                                else
                                {
                                    intervalValuas.Add(i, 0);
                                }
                            }
                        }
                        else // 累加值
                        {
                            UInt64 dRecordId;
                            if (rbChartTypePie.Checked && rbMeterCompare.Checked)  // 设备对标（饼状图）
                            {
                                dRecordId = (UInt64)((UInt64)item.GlobalId << 32) + (UInt64)((dtpFrom.Value.Day + 1) << 16);
                                recordId = (UInt64)((UInt64)item.GlobalId << 32) + (UInt64)(dtpFrom.Value.Day << 16) + (UInt64)(0 << 8);
                                if (data.ContainsKey(recordId) && data.ContainsKey(dRecordId))
                                {
                                    intervalValuas.Add(0, data[dRecordId] - data[recordId]);

                                }
                                else
                                {
                                    intervalValuas.Add(0, 0);
                                }
                                goto DAYADD;
                            }
                            for (i = 0; i < 24; i++) // 每行
                            {
                                if (i == 23)
                                {
                                    dRecordId = (UInt64)((UInt64)item.GlobalId << 32) + (UInt64)((dtpFrom.Value.Day + 1) << 16);
                                }
                                else
                                {
                                    dRecordId = (UInt64)((UInt64)item.GlobalId << 32) + (UInt64)(dtpFrom.Value.Day << 16) + (UInt64)((i + 1) << 8); ;
                                }
                                recordId = (UInt64)((UInt64)item.GlobalId << 32) + (UInt64)(dtpFrom.Value.Day << 16) + (UInt64)(i << 8);
                                if (data.ContainsKey(recordId) && data.ContainsKey(dRecordId))
                                {
                                    intervalValuas.Add(i, data[dRecordId] - data[recordId]);

                                }
                                else
                                {
                                    intervalValuas.Add(i, 0);
                                }
                            }
                        }
                    DAYADD:
                        recValues.Add(item, intervalValuas);
                    }
                    break;
                #endregion
                #region  月报数据统计
                case eQueryType.month:
                    maxday = GetMonthMaxDay(dtpFrom.Value.Year, dtpFrom.Value.Month); // 最大天数
                    foreach (var item in SelectedItem)
                    {
                        intervalValuas = new Dictionary<double, double>();
                        if (!item.dataItem.IsSummation) // 瞬时值
                        {
                            if (rbChartTypePie.Checked && rbMeterCompare.Checked) // 设备对标（饼状图）
                            {
                                recordId = (UInt64)((UInt64)item.GlobalId << 32) + (UInt64)(1 << 16);
                                if (data.ContainsKey(recordId))
                                {
                                    intervalValuas.Add(0, data[recordId]);
                                }
                                else
                                {
                                    intervalValuas.Add(0, 0);
                                }
                                goto MONTHADD;
                            }
                            for (i = 0; i < maxday; i++) // 每行
                            {
                                recordId = (UInt64)((UInt64)item.GlobalId << 32) + (UInt64)((i + 1) << 16);
                                if (data.ContainsKey(recordId))
                                {
                                    intervalValuas.Add(i, data[recordId]);
                                }
                                else
                                {
                                    intervalValuas.Add(i, 0);
                                }
                            }
                        }
                        else // 累加值
                        {
                            UInt64 mRecordId = 0;
                            if (rbChartTypePie.Checked && rbMeterCompare.Checked)  // 设备对标（饼状图）
                            {
                                recordId = (UInt64)((UInt64)item.GlobalId << 32);
                                mRecordId = (UInt64)((UInt64)item.GlobalId << 32) + (UInt64)65536;
                                if (QueryResultListTag.ContainsKey(mRecordId) && data.ContainsKey(recordId))
                                {

                                    intervalValuas.Add(0, QueryResultListTag[mRecordId] - data[recordId]);
                                }
                                else
                                {
                                    intervalValuas.Add(0, 0);
                                }
                                goto MONTHADD;
                            }
                            for (i = 0; i < 31; i++) // 每行
                            {
                                if (maxday == i + 1)
                                {
                                    recordId = (UInt64)((UInt64)item.GlobalId << 32) + (UInt64)((Int32)(maxday << 16));
                                    mRecordId = (UInt64)((UInt64)item.GlobalId << 32) + (UInt64)65536;
                                    if (QueryResultListTag.ContainsKey(mRecordId) && data.ContainsKey(recordId))
                                    {

                                        intervalValuas.Add(i, QueryResultListTag[mRecordId] - data[recordId]);
                                    }
                                    else
                                    {
                                        intervalValuas.Add(i, 0);
                                    }
                                }
                                else if (maxday > i)
                                {
                                    recordId = (UInt64)((UInt64)item.GlobalId << 32) + (UInt64)((i + 1) << 16);
                                    mRecordId = (UInt64)((UInt64)item.GlobalId << 32) + (UInt64)((i + 2) << 16);
                                    if (data.ContainsKey(recordId) && data.ContainsKey(mRecordId))
                                    {
                                        intervalValuas.Add(i, data[mRecordId] - data[recordId]);

                                    }
                                    else
                                    {
                                        intervalValuas.Add(i, 0);
                                    }
                                }
                                else
                                {
                                    continue;
                                }
                            }
                        }
                    MONTHADD:
                        recValues.Add(item, intervalValuas);
                    }
                    break;
                #endregion
                #region  年报数据统计
                case eQueryType.year:
                    foreach (var item in SelectedItem)
                    {
                        intervalValuas = new Dictionary<double, double>();
                        if (!item.dataItem.IsSummation)
                        {
                            if (rbChartTypePie.Checked && rbMeterCompare.Checked) // 设备对标（饼状图）
                            {
                                recordId = (UInt64)((UInt64)item.GlobalId << 32) + (UInt64)(12 << 24) + (UInt64)((Int32)(maxday << 16) + (Int32)(23 << 8) + (60 - item.dataItem.SaveCycle));
                                if (data.ContainsKey(recordId))
                                {
                                    intervalValuas.Add(0, data[recordId]);
                                }
                                else
                                {
                                    intervalValuas.Add(0, 0);
                                }
                                goto YEARADD;
                            }
                            for (i = 0; i < 12; i++) // 每行
                            {
                                maxday = GetMonthMaxDay(dtpFrom.Value.Year, i + 1);
                                recordId = (UInt64)((UInt64)item.GlobalId << 32) + (UInt64)((i + 1) << 24) + (UInt64)((Int32)(maxday << 16) + (Int32)(23 << 8) + (60 - item.dataItem.SaveCycle));
                                if (data.ContainsKey(recordId))
                                {
                                    intervalValuas.Add(i, data[recordId]);
                                }
                                else
                                {
                                    intervalValuas.Add(i, 0);
                                }
                            }
                        }
                        else
                        {
                            UInt64 yRecordId;
                            if (rbChartTypePie.Checked && rbMeterCompare.Checked)  // 设备对标（饼状图）
                            {
                                recordId = (UInt64)((UInt64)item.GlobalId << 32) + (UInt64)(1 << 24) + (UInt64)65536;
                                yRecordId = (UInt64)((UInt64)item.GlobalId << 32) + (UInt64)(12 << 24) + (UInt64)((Int32)(maxday << 16) + (Int32)(23 << 8) + (60 - item.dataItem.SaveCycle));
                                if (data.ContainsKey(recordId) && data.ContainsKey(yRecordId))
                                {
                                    intervalValuas.Add(0, data[yRecordId] - data[recordId]);
                                }
                                else
                                {
                                    intervalValuas.Add(0, 0);
                                }
                                goto YEARADD;
                            }
                            for (i = 0; i < 12; i++) // 每行
                            {
                                recordId = (UInt64)((UInt64)item.GlobalId << 32) + (UInt64)((i + 1) << 24) + (UInt64)65536;
                                yRecordId = (UInt64)((UInt64)item.GlobalId << 32) + (UInt64)((i + 1) << 24) + (UInt64)((Int32)(maxday << 16) + (Int32)(23 << 8) + (60 - item.dataItem.SaveCycle));
                                if (data.ContainsKey(recordId) && data.ContainsKey(yRecordId))
                                {
                                    intervalValuas.Add(i, data[yRecordId] - data[recordId]);
                                }
                                else
                                {
                                    intervalValuas.Add(i, 0);
                                }
                            }
                        }
                    YEARADD:
                        recValues.Add(item, intervalValuas);
                    }
                    break;
                #endregion
                #region 自定义报表数据统计
                case eQueryType.custom:
                    List<UInt32> savetime = new List<UInt32>();
                    UInt32 tempValue = 0;
                    foreach (var item in data)
                    {
                        tempValue = (UInt32)item.Key;
                        if (!savetime.Contains(tempValue))
                        {
                            savetime.Add(tempValue);
                        }
                    }
                    foreach (var item in SelectedItem)
                    {
                        intervalValuas = new Dictionary<double, double>();
                        for (i = 0; i < savetime.Count; i++) // 每行
                        {
                            recordId = (UInt64)((UInt64)item.GlobalId << 32) + (UInt32)savetime[i];
                            if (data.ContainsKey(recordId))
                            {
                                intervalValuas.Add(savetime[i], data[recordId]);
                            }
                            else
                            {
                                intervalValuas.Add(savetime[i], 0);
                            }
                        }
                        recValues.Add(item, intervalValuas);
                    }
                    break;
                #endregion

                default:
                    break;
            }
            k = 0;
            #region  设备对标（饼状图）
            if (rbChartTypePie.Checked && rbMeterCompare.Checked)
            {
                Dictionary<string, double> metersValue = new Dictionary<string, double>();
                foreach (var sss in recValues)
                {
                    dataItem = sss.Key.dataItem;
                    if (dataItem == null)
                    {
                        continue;
                    }
                    BaseDevice dev = AppMain.ChlList[(int)sss.Key.ChannelId].GetDevByIndex((int)sss.Key.DeviceId);
                    string dataName;
                    if (dev != null)
                    {
                        dataName = dev.Name + dataItem.Name;
                    }
                    else
                    {
                        dataName = dataItem.Name;
                    }
                    intervalValuas = sss.Value;
                    metersValue.Add(dataName, intervalValuas[0]);
                }
                if (metersValue.Count > 0)
                {
                    string datetime = "";
                    switch (queryType)
                    {
                        case eQueryType.day:
                            datetime = string.Format("{0}", dtpFrom.Value.ToString("yyyy-MM-dd"));
                            break;
                        case eQueryType.month:
                            datetime = string.Format("{0}", dtpFrom.Value.ToString("yyyy-MM"));
                            break;
                        case eQueryType.year:
                            datetime = string.Format("{0}", dtpFrom.Value.ToString("yyyy"));
                            break;
                        default:
                            datetime = string.Format("{0}", dtpFrom.Value.ToString("yyyy-MM-dd"));
                            break;
                    }
                    System.Windows.Forms.DataVisualization.Charting.Series item = new System.Windows.Forms.DataVisualization.Charting.Series(datetime);
                    System.Drawing.Color clr = AppMain.AvailableColors[k];
                    k++;
                    item.Color = clr;
                    item.BorderWidth = 3;
                    item.MarkerColor = Color.Gray;
                    item.MarkerStyle = System.Windows.Forms.DataVisualization.Charting.MarkerStyle.Circle;
                    item.IsValueShownAsLabel = true;
                    SetSeriesChartType(item);
                    foreach (var val in metersValue)
                        item.Points.AddXY(val.Key, val.Value);
                    WaveRecChart.Series.Add(item);
                    System.Windows.Forms.DataVisualization.Charting.Legend leg = new System.Windows.Forms.DataVisualization.Charting.Legend(item.Name);
                    leg.ForeColor = item.Color;
                    leg.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Right;
                    leg.DockedToChartArea = "ChartArea1";
                    leg.TextWrapThreshold = 15;
                    WaveRecChart.Legends.Add(leg);
                }
                return;
            }
            #endregion

            foreach (var sss in recValues)
            {
                dataItem = sss.Key.dataItem;
                if (dataItem == null)
                {
                    continue;
                }
                BaseDevice dev = AppMain.ChlList[(int)sss.Key.ChannelId].GetDevByIndex((int)sss.Key.DeviceId);
                string dataName;
                if (dev != null)
                {
                    dataName = dev.Name + dataItem.Name;
                }
                else
                {
                    dataName = dataItem.Name;
                }
                intervalValuas = sss.Value;
                System.Windows.Forms.DataVisualization.Charting.Series item = new System.Windows.Forms.DataVisualization.Charting.Series(dataName);
                System.Drawing.Color clr = AppMain.AvailableColors[k];
                k++;
                item.Color = clr;
                item.Legend = dataName;
                item.BorderWidth = 3;
                item.MarkerColor = Color.Gray;
                item.MarkerStyle = System.Windows.Forms.DataVisualization.Charting.MarkerStyle.Circle;
                item.IsValueShownAsLabel = true;
                SetSeriesChartType(item);
                if (queryType == eQueryType.custom)
                {
                    uint day, hour, min;
                    foreach (var val in intervalValuas)
                    {
                        day = ((uint) val.Key) >> 16;
                        hour = (((uint)val.Key) >> 8) &0xFF;
                        min = ((uint)val.Key) & 0xFF;
                        item.Points.AddXY(string.Format("{0}-{1} {2}:{3}",dtpFrom.Value.Month,day,hour,min), val.Value);
                    }
                        
                }
                else
                {
                    foreach (var val in intervalValuas)
                        item.Points.AddXY(val.Key + 1, val.Value);
                }
              
                WaveRecChart.Series.Add(item);
                System.Windows.Forms.DataVisualization.Charting.Legend leg = new System.Windows.Forms.DataVisualization.Charting.Legend(item.Name);
                leg.ForeColor = item.Color;
                leg.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Left;
                leg.DockedToChartArea = "ChartArea1";
                leg.TextWrapThreshold = 15;
                WaveRecChart.Legends.Add(leg);
            }
            WaveRecChart.Invalidate();
        }


        UInt32 dataidFrom = 0, dataidTo = 100;
        /// <summary>
        ///  保存查询结果（数据项标号，时标，数值；自定义查询时为时标，数据项标号，数值）
        /// </summary>
        Dictionary<UInt64, float> QueryResultList = new Dictionary<UInt64, float>();  // 某个数据项的不同时刻的值
        Dictionary<UInt64, float> QueryResultListTag = new Dictionary<UInt64, float>();  // 某个数据项的不同时刻的值(附加)
        private void btnQuery_Click(object sender, EventArgs e)
        {
            if (!GetSelectedItem())
            {
                MessageBox.Show(Resources.txtSelectErr, Properties.Resources.msgTitleTip, MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            if (SelectedItem == null || SelectedItem.Count == 0)
            {
                //ControlExs.QQMessageBox.Show(null, Color.Green, "请选择需要查询的数据点!");
                MessageBox.Show(Resources.txtSelectNothing, Properties.Resources.msgTitleTip, MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            string strTable0 = "", strTable1 = "";
            string strSQL = "", strSQLAll = "";

            strTable0 = Properties.Resources.HistoryTableName + dtpFrom.Value.ToString("yyyyMM");
            strTable1 = Properties.Resources.HistoryTableName + dtpTo.Value.ToString("yyyyMM");

            try
            {
                switch (queryType)
                {
                    case eQueryType.day:
                        strSQL = string.Format("savetime >= {0:D} and savetime <= {1:D} and (savetime mod 256=0) ", (Int32)(dtpFrom.Value.Day << 16), (Int32)((dtpFrom.Value.Day + 1) << 16));
                        break;
                    case eQueryType.month:
                        strSQL = "savetime % 65536=0";
                        break;
                    case eQueryType.year:
                        strSQL = string.Format("select name from MSysObjects where type=1 and flags=0 and name like '{0}%'", Properties.Resources.HistoryTableName + dtpFrom.Value.Year.ToString("D4"));
                        break;
                    case eQueryType.custom:
                        if (dtpTo.Value <= dtpFrom.Value || dtpTo.Value.Month != dtpFrom.Value.Month)
                        {
                            MessageBox.Show(Resources.txtSelectErrDate);
                            break;
                        }
                        strSQL = string.Format("savetime >= {0:D} and savetime <= {1:D}", (Int32)(dtpFrom.Value.Day << 16) + (Int32)(dtpFrom.Value.Hour << 8) + dtpFrom.Value.Minute,
                        (Int32)(dtpTo.Value.Day << 16) + (Int32)(dtpTo.Value.Hour << 8) + dtpTo.Value.Minute);
                        break;
                }
                if (strSQL == "")
                {
                    return;
                }
                QueryResultList.Clear();
                QueryResultListTag.Clear();

                UInt64 ItemId, TimeId;
                UInt64 RecordId;
                float fValue;
                DataTable dbTable = new DataTable();
                WaitingForm waiting = new WaitingForm((obj, arg) =>
                {
                        #region 自定义查询

                    if (queryType == eQueryType.custom) //  
                    {
                        if (SelectedDevices.Count > 0)
                        {
                            foreach (var dev in SelectedDevices)
                            {
                                if (dev.GetDataItemCnt() > 0)
                                {
                                    dataidFrom = (UInt32) (dev.ChannelId << 24) + (UInt32) (dev.DeviceId << 16) +
                                                 (UInt32) dev.GetDataItem(0).ItemId;
                                    dataidTo = (UInt32) (dev.ChannelId << 24) + (UInt32) (dev.DeviceId << 16) +
                                               (UInt32) dev.GetDataItem(dev.GetDataItemCnt() - 1).ItemId + 1;
                                }
                                else
                                {
                                    continue;
                                }
                                strSQLAll =
                                    string.Format(
                                        "select * from (select * from {0} where dataid >={1} and dataid < {2}) as OneDev  where {3}",
                                        strTable0, dataidFrom, dataidTo, strSQL);
                                dbTable = dbOper.GetDataTable(strSQLAll);
                                if (dbTable != null && dbTable.Rows.Count > 0)
                                {
                                    foreach (DataRow row in dbTable.Rows)
                                    {
                                        ItemId = Convert.ToUInt64(row.ItemArray[0]); // (UInt64)row.ItemArray[0] 会报错
                                        TimeId = Convert.ToUInt64(row.ItemArray[1]);
                                        RecordId = (UInt64) (ItemId << 32) + TimeId;
                                        fValue = Convert.ToSingle(row.ItemArray[2]);
                                        QueryResultList.Add(RecordId, fValue);
                                    }
                                }

                            }
                        }

                        if (LooseSelItem.Count > 0)
                        {
                            foreach (var item in LooseSelItem)
                            {
                                strSQLAll =
                                    string.Format(
                                        "select * from (select * from {0} where dataid={1} ) as OneDev  where {2}",
                                        strTable0, item.GlobalId, strSQL);
                                dbTable = dbOper.GetDataTable(strSQLAll);
                                if (dbTable == null || dbTable.Rows.Count == 0)
                                {
                                    continue;
                                }
                                foreach (DataRow row in dbTable.Rows)
                                {
                                    ItemId = Convert.ToUInt64(row.ItemArray[0]);
                                    TimeId = Convert.ToUInt64(row.ItemArray[1]);
                                    RecordId = (UInt64) (ItemId << 32) + TimeId;
                                    fValue = Convert.ToSingle(row.ItemArray[2]);
                                    QueryResultList.Add(RecordId, fValue);
                                }
                            }

                        }

                    }
                        #endregion
                        #region 年报查询

                    else if (queryType == eQueryType.year) // 年份查询
                    {
                        List<string> strtabName = new List<string>();
                        DataTable dtTableName = dbOper.GetDataTable(strSQLAll);
                        if (dtTableName == null)
                        {
                            MessageBox.Show(Resources.txtNothingSaved, Properties.Resources.msgTitleTip);
                            return;
                        }
                        foreach (DataRow row in dtTableName.Rows)
                        {
                            strtabName.Add((string) row.ItemArray[0]);
                        }

                        for (int i = 0; i < strtabName.Count; i++)
                        {
                            UInt64 month = UInt64.Parse(strtabName[i].Substring(strtabName[i].Length - 2, 2));
                            int maxday = GetMonthMaxDay(dtpFrom.Value.Year, (int) month);
                            if (SelectedItem.Count > 0)
                            {
                                foreach (var item in SelectedItem)
                                {
                                    strSQLAll =
                                        string.Format(
                                            "select * from (select * from {0} where dataid ={1}) as OneDev  where (savetime=65536 or savetime={2})",
                                            strtabName[i], item.GlobalId,
                                            (Int32) (maxday << 16) + (Int32) (23 << 8) +
                                            (Int32) (60 - item.dataItem.SaveCycle));
                                    dbTable = dbOper.GetDataTable(strSQLAll);
                                    if (dbTable == null || dbTable.Rows.Count == 0)
                                    {
                                        continue;
                                    }
                                    foreach (DataRow row in dbTable.Rows)
                                    {
                                        ItemId = Convert.ToUInt64(row.ItemArray[0]);
                                        TimeId = Convert.ToUInt64(row.ItemArray[1]);
                                        RecordId = (UInt64) (ItemId << 32) + TimeId + (UInt64) (month << 24);
                                        //RecordId = (UInt64)(ItemId << 32) + month;
                                        fValue = Convert.ToSingle(row.ItemArray[2]);
                                        QueryResultList.Add(RecordId, fValue);
                                    }
                                }
                            }
                        }

                    }
                        #endregion
                        #region 月报查询

                    else if (queryType == eQueryType.month) // 月份查询
                    {
                        strTable1 = Properties.Resources.HistoryTableName +
                                    dtpFrom.Value.AddMonths(1).ToString("yyyyMM");
                        if (SelectedDevices.Count > 0)
                        {
                            foreach (var dev in SelectedDevices)
                            {
                                if (dev.GetDataItemCnt() > 0)
                                {
                                    dataidFrom = (UInt32) (dev.ChannelId << 24) + (UInt32) (dev.DeviceId << 16) +
                                                 (UInt32) dev.GetDataItem(0).ItemId;
                                    dataidTo = (UInt32) (dev.ChannelId << 24) + (UInt32) (dev.DeviceId << 16) +
                                               (UInt32) dev.GetDataItem(dev.GetDataItemCnt() - 1).ItemId + 1;
                                }
                                else
                                {
                                    continue;
                                }
                                strSQLAll =
                                    string.Format(
                                        "select * from (select * from {0} where dataid >={1} and dataid < {2}) as OneDev  where {3}",
                                        strTable0, dataidFrom, dataidTo, strSQL);
                                dbTable = dbOper.GetDataTable(strSQLAll);
                                if (dbTable != null || dbTable.Rows.Count > 0)
                                {
                                    foreach (DataRow row in dbTable.Rows)
                                    {
                                        ItemId = Convert.ToUInt64(row.ItemArray[0]);
                                        TimeId = Convert.ToUInt64(row.ItemArray[1]);
                                        RecordId = (UInt64) (ItemId << 32) + TimeId;
                                        fValue = Convert.ToSingle(row.ItemArray[2]);
                                        QueryResultList.Add(RecordId, fValue);
                                    }
                                }
                                strSQLAll =
                                    string.Format(
                                        "select * from (select * from {0} where dataid >={1} and dataid < {2}) as OneDev  where savetime =65536",
                                        strTable1, dataidFrom, dataidTo);
                                dbTable = dbOper.GetDataTable(strSQLAll);
                                if (dbTable != null || dbTable.Rows.Count > 0)
                                {
                                    foreach (DataRow row in dbTable.Rows)
                                    {
                                        ItemId = Convert.ToUInt64(row.ItemArray[0]);
                                        TimeId = Convert.ToUInt64(row.ItemArray[1]);
                                        RecordId = (UInt64) (ItemId << 32) + TimeId;
                                        fValue = Convert.ToSingle(row.ItemArray[2]);
                                        QueryResultListTag.Add(RecordId, fValue);
                                    }
                                }
                            }
                        }
                        if (LooseSelItem.Count > 0)
                        {
                            foreach (var item in LooseSelItem)
                            {
                                strSQLAll =
                                    string.Format(
                                        "select * from (select * from {0} where dataid={1} ) as OneDev  where {2}",
                                        strTable0, item.GlobalId, strSQL);
                                dbTable = dbOper.GetDataTable(strSQLAll);
                                if (dbTable == null || dbTable.Rows.Count == 0)
                                {
                                    continue;
                                }
                                foreach (DataRow row in dbTable.Rows)
                                {
                                    ItemId = Convert.ToUInt64(row.ItemArray[0]);
                                    TimeId = Convert.ToUInt64(row.ItemArray[1]);
                                    RecordId = (UInt64) (ItemId << 32) + TimeId;
                                    fValue = Convert.ToSingle(row.ItemArray[2]);
                                    QueryResultList.Add(RecordId, fValue);
                                }
                                if (!item.dataItem.IsSummation)
                                {
                                    continue;
                                }
                                strSQLAll =
                                    string.Format(
                                        "select * from (select * from {0} where dataid={1} ) as OneDev  where savetime =65536",
                                        strTable1, item.GlobalId);
                                dbTable = dbOper.GetDataTable(strSQLAll);
                                if (dbTable == null || dbTable.Rows.Count == 0)
                                {
                                    continue;
                                }
                                foreach (DataRow row in dbTable.Rows)
                                {
                                    ItemId = Convert.ToUInt64(row.ItemArray[0]);
                                    TimeId = Convert.ToUInt64(row.ItemArray[1]);
                                    RecordId = (UInt64) (ItemId << 32) + TimeId;
                                    fValue = Convert.ToSingle(row.ItemArray[2]);
                                    QueryResultListTag.Add(RecordId, fValue);
                                }
                            }
                        }
                    }
                        #endregion
                        #region 日报查询

                    else // 日报查询
                    {
                        if (SelectedDevices.Count > 0)
                        {
                            foreach (var dev in SelectedDevices)
                            {
                                if (dev.GetDataItemCnt() > 0)
                                {
                                    dataidFrom = (UInt32) (dev.ChannelId << 24) + (UInt32) (dev.DeviceId << 16) +
                                                 (UInt32) dev.GetDataItem(0).ItemId;
                                    dataidTo = (UInt32) (dev.ChannelId << 24) + (UInt32) (dev.DeviceId << 16) +
                                               (UInt32) dev.GetDataItem(dev.GetDataItemCnt() - 1).ItemId + 1;
                                }
                                else
                                {
                                    continue;
                                }
                                strSQLAll =
                                    string.Format(
                                        "select * from (select * from {0} where dataid >={1} and dataid < {2}) as OneDev  where {3}",
                                        strTable0, dataidFrom, dataidTo, strSQL);
                                dbTable = dbOper.GetDataTable(strSQLAll);
                                if (dbTable != null || dbTable.Rows.Count > 0)
                                {
                                    foreach (DataRow row in dbTable.Rows)
                                    {
                                        ItemId = Convert.ToUInt64(row.ItemArray[0]);
                                        TimeId = Convert.ToUInt64(row.ItemArray[1]);
                                        RecordId = (UInt64) (ItemId << 32) + TimeId;
                                        fValue = Convert.ToSingle(row.ItemArray[2]);
                                        QueryResultList.Add(RecordId, fValue);
                                    }
                                }
                            }
                        }
                        if (LooseSelItem.Count > 0)
                        {
                            foreach (var item in LooseSelItem)
                            {
                                strSQLAll =
                                    string.Format(
                                        "select * from (select * from {0} where dataid={1} ) as OneDev  where {2}",
                                        strTable0, item.GlobalId, strSQL);
                                dbTable = dbOper.GetDataTable(strSQLAll);
                                if (dbTable == null || dbTable.Rows.Count == 0)
                                {
                                    continue;
                                }
                                foreach (DataRow row in dbTable.Rows)
                                {
                                    ItemId = Convert.ToUInt64(row.ItemArray[0]);
                                    TimeId = Convert.ToUInt64(row.ItemArray[1]);
                                    RecordId = (UInt64) (ItemId << 32) + TimeId;
                                    fValue = Convert.ToSingle(row.ItemArray[2]);
                                    QueryResultList.Add(RecordId, fValue);
                                }
                            }
                        }
                    }

                    #endregion
                }, false, false);
                waiting.ShowDialog();
                FillDataToChart(queryType, QueryResultList); // 显示查询结果
                foreach (var sss in WaveRecChart.Series)
                {
                    if (tsmiShowValueLabel.Checked)
                    {
                        sss.IsValueShownAsLabel = true;
                        sss.LabelFormat = "F2";
                        sss.MarkerStyle = System.Windows.Forms.DataVisualization.Charting.MarkerStyle.Circle;
                    }
                    else
                    {
                        sss.MarkerStyle = System.Windows.Forms.DataVisualization.Charting.MarkerStyle.None;
                        sss.ResetIsValueShownAsLabel();
                    }
                }
            }
            catch (System.Exception ex)
            {
                MessageBox.Show(ex.Message);
                return;
            }




        }

        /// <summary>
        /// 导出到Excel
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnExport_Click(object sender, EventArgs e)
        {
            SaveFileDialog save = new SaveFileDialog();
            save.DefaultExt = "png";
            save.AddExtension = true;
            save.Filter = Resources.txtPictureFilter;//
            save.Title = Resources.txtExportPath;
            if (save.ShowDialog() != System.Windows.Forms.DialogResult.OK)
            {
                return;
            }

            string path = save.FileName;
            WaveRecChart.SaveImage(path, System.Drawing.Imaging.ImageFormat.Png);
        }
        private void btnPrint_Click(object sender, EventArgs e)
        {
            if (WaveRecChart.Series.Count>0)
            {
                WaveRecChart.Printing.Print(true);
            }
        }

        private void rbTimeCompare_CheckedChanged(object sender, EventArgs e)
        {
            if (rbTimeCompare.Checked)
            {
                LimitSeriesNum = 1;
            }
            else
            {
                LimitSeriesNum = 30;
            }
        }

        private void tsmiShowValueLabel_Click(object sender, EventArgs e)
        {
            tsmiShowValueLabel.Checked = !tsmiShowValueLabel.Checked;
            foreach (var sss in WaveRecChart.Series)
            {
                if (tsmiShowValueLabel.Checked)
                {
                    sss.IsValueShownAsLabel = true;
                    sss.LabelFormat = "F2";
                    sss.MarkerStyle = System.Windows.Forms.DataVisualization.Charting.MarkerStyle.Circle;
                }
                else
                {
                    sss.MarkerStyle = System.Windows.Forms.DataVisualization.Charting.MarkerStyle.None;
                    sss.ResetIsValueShownAsLabel();
                }
            }

        }

      

        private void rbChartTypeColumn_CheckedChanged(object sender, EventArgs e)
        {
            rbCustom.Visible = true;
            gpCompare.Visible = false;
            if (rbChartTypeColumn.Checked)
            {
                LimitSeriesNum = 6;
                foreach (var sss in WaveRecChart.Series)
                {
                    SetSeriesChartType(sss);
                }
            }
            else if (rbChartTypeLine.Checked)
            {
                LimitSeriesNum = 6;
                foreach (var sss in WaveRecChart.Series)
                {
                    SetSeriesChartType(sss);
                }
            }
            else
            {
                gpCompare.Visible = true;
                if (rbTimeCompare.Checked)
                {
                    LimitSeriesNum = 1;
                }
                else
                {
                    LimitSeriesNum = 30;
                }
                rbCustom.Visible = false;
                rbDay.Checked = true;
                for (int i = WaveRecChart.Series.Count - 1; i >= 0; i--)
                {
                    var sss = WaveRecChart.Series[i];
                    if (i == 0)
                    {
                        SetSeriesChartType(sss);
                        continue;
                    }
                    WaveRecChart.Series.Remove(sss);
                }
            }

        }
    }
    public class DataItemTag
    {
        public UInt32 ChannelId;
        public UInt32 DeviceId;
        public UInt32 DataItemId;
        public DevDataItem dataItem;
        public UInt32 GlobalId
        {
            get { return (UInt32)((UInt32)(ChannelId << 24) + (UInt32)(DeviceId << 16) + DataItemId); }
        }
        public DataItemTag(UInt32 chlId, UInt32 devId, DevDataItem item)
        {
            ChannelId = chlId;
            DeviceId = devId;
            dataItem = item;
            if (item != null)
                DataItemId = (UInt32)item.ItemId;
        }
        public DataItemTag(UInt32 chlId, UInt32 devId, UInt32 itemid)
        {
            ChannelId = chlId;
            DeviceId = devId;
            DataItemId = itemid;
            try
            {
                dataItem = AppMain.ChlList[(int)chlId].GetDevByIndex((int)devId).GetDataItem((int)itemid);
            }
            catch
            {
            }
        }
    }
}
